/****************************************************************
 *  This file created by writerB.php on 03/20/2007 at 20:48:26  *
 ****************************************************************
 *  writerB.php created by Tonk (tonk@ctonk.com) in 2007        *
 ****************************************************************
 *                 General Document Information
 *
 *  File Name: creature.cpp
 *  Class Name: Creature
 *  Data members: 40
 *  Notes:
 ****************************************************************/

#include <iostream>
#include <vector>
#include "combined.h"
#include "log.h"
#include "stringutil.h"
#include "world.h"



int Creature::numCreatures = 0;
int Creature::creatureIndex = 0;


// Default constructor...
Creature::Creature() {
	setCreatureID( ++creatureIndex );
	setName( "default" );
	setShortDesc( "default" );
	setLongDesc( "default" );
	setStrWeight( "average" );
	setStrHeight( "average" );
	setArea( NULL );
	setCreature( NULL );
	setMob( NULL );
	setCharacter( NULL );
	setPos( 0 );
	setRace( 0 );
	setClass( 0 );
	setLevel( 0 );
	setStr( 0 );
	setMaxStr( 0 );
	setDex( 0 );
	setMaxDex( 0 );
	setCon( 0 );
	setMaxCon( 0 );
	setIntel( 0 );
	setMaxIntel( 0 );
	setWis( 0 );
	setMaxWis( 0 );
	setCha( 0 );
	setMaxCha( 0 );
	setHp( 0 );
	setMaxHp( 0 );
	setMana( 0 );
	setMaxMana( 0 );
	setMove( 0 );
	setMaxMove( 0 );
	setAc( 0 );
	setAcBash( 0 );
	setAcSlash( 0 );
	setAcPierce( 0 );
	setAcExotic( 0 );
	setHr( 0 );
	setDr( 0 );
	setSaves( 0 );
	setWimpy( 0 );
	setGender( 0 );
	setHeight( 0 );
	setWeight( 0 );
	setAge( 0 );
	setGold( 0 );
	setSilver( 0 );
	// Increment the object count...
	numCreatures++;
}

// Additional constructors...

// Copy constructor (Doesn't change _CreatureID)...
Creature::Creature( const Creature& ref ) {
	setCreatureID( ++creatureIndex );
	setName( ref.getName() );
	setShortDesc( ref.getShortDesc() );
	setLongDesc( ref.getLongDesc() );
	setFullDesc( ref.getFullDesc() );
	setStrHeight( ref.getStrHeight() );
	setStrWeight( ref.getStrWeight() );
	setArea( ref.getArea() );
	setCreature( ref.getCreature() );
	setMob( ref.getMob() );
	setCharacter( ref.getCharacter() );
	setPos( ref.getPos() );
	setRace( ref.getRace() );
	setClass( ref.getClass() );
	setLevel( ref.getLevel() );
	setStr( ref.getStr() );
	setMaxStr( ref.getMaxStr() );
	setDex( ref.getDex() );
	setMaxDex( ref.getMaxDex() );
	setCon( ref.getCon() );
	setMaxCon( ref.getMaxCon() );
	setIntel( ref.getIntel() );
	setMaxIntel( ref.getMaxIntel() );
	setWis( ref.getWis() );
	setMaxWis( ref.getMaxWis() );
	setCha( ref.getCha() );
	setMaxCha( ref.getMaxCha() );
	setHp( ref.getHp() );
	setMaxHp( ref.getMaxHp() );
	setMana( ref.getMana() );
	setMaxMana( ref.getMaxMana() );
	setMove( ref.getMove() );
	setMaxMove( ref.getMaxMove() );
	setAc( ref.getAc() );
	setAcBash( ref.getAcBash() );
	setAcSlash( ref.getAcSlash() );
	setAcPierce( ref.getAcPierce() );
	setAcExotic( ref.getAcExotic() );
	setHr( ref.getHr() );
	setDr( ref.getDr() );
	setSaves( ref.getSaves() );
	setWimpy( ref.getWimpy() );
	setGender( ref.getGender() );
	setHeight( ref.getHeight() );
	setWeight( ref.getWeight() );
	setAge( ref.getAge() );
	setGold( ref.getGold() );
	setSilver( ref.getSilver() );
	// Increment the object count...
	numCreatures++;
}

// Destructor...
Creature::~Creature() {
	setArea( NULL );
	setCreature( NULL );
	setMob( NULL );
	setCharacter( NULL );
	// Decrement the object count...
	numCreatures--;
}

// Assignment operator (Doesn't change _CreatureID)...
Creature& Creature::operator = ( const Creature& ref ) {
	setName( ref.getName() );
	setShortDesc( ref.getShortDesc() );
	setLongDesc( ref.getLongDesc() );
	setFullDesc( ref.getFullDesc() );
	setStrHeight( ref.getStrHeight() );
	setStrWeight( ref.getStrWeight() );
	setArea( ref.getArea() );
	setCreature( ref.getCreature() );
	setMob( ref.getMob() );
	setCharacter( ref.getCharacter() );
	setPos( ref.getPos() );
	setRace( ref.getRace() );
	setClass( ref.getClass() );
	setLevel( ref.getLevel() );
	setStr( ref.getStr() );
	setMaxStr( ref.getMaxStr() );
	setDex( ref.getDex() );
	setMaxDex( ref.getMaxDex() );
	setCon( ref.getCon() );
	setMaxCon( ref.getMaxCon() );
	setIntel( ref.getIntel() );
	setMaxIntel( ref.getMaxIntel() );
	setWis( ref.getWis() );
	setMaxWis( ref.getMaxWis() );
	setCha( ref.getCha() );
	setMaxCha( ref.getMaxCha() );
	setHp( ref.getHp() );
	setMaxHp( ref.getMaxHp() );
	setMana( ref.getMana() );
	setMaxMana( ref.getMaxMana() );
	setMove( ref.getMove() );
	setMaxMove( ref.getMaxMove() );
	setAc( ref.getAc() );
	setAcBash( ref.getAcBash() );
	setAcSlash( ref.getAcSlash() );
	setAcPierce( ref.getAcPierce() );
	setAcExotic( ref.getAcExotic() );
	setHr( ref.getHr() );
	setDr( ref.getDr() );
	setSaves( ref.getSaves() );
	setWimpy( ref.getWimpy() );
	setGender( ref.getGender() );
	setHeight( ref.getHeight() );
	setWeight( ref.getWeight() );
	setAge( ref.getAge() );
	setGold( ref.getGold() );
	setSilver( ref.getSilver() );
	return *this;
}

// Equality operator (Compares _level)...
bool Creature::operator == ( const Creature& ref ) const {
	return	( getLevel() == ref.getLevel() );
}

// Inequality operator (Compares _level)...
bool Creature::operator != ( const Creature& ref ) const {
	return	( getLevel() != ref.getLevel() );
}

// Less than operator (Compares _level)...
bool Creature::operator < ( const Creature& ref ) const {
	return ( getLevel() < ref.getLevel() );
}

// Greater than operator (Compares _level)...
bool Creature::operator > ( const Creature& ref ) const {
	return ( getLevel() > ref.getLevel() );
}

// Protected Methods...
void Creature::setCreatureID( const int& CreatureID ) {
	_CreatureID = CreatureID;
}

// Public accessor methods...
int Creature::getCreatureID( void ) const {
	return _CreatureID;
}

void Creature::setName( const std::string& name ) {
	_name = name;
	return;
}

std::string Creature::getName( void ) const {
	return _name;
}

void Creature::setShortDesc( const std::string& shortDesc ) {
	_shortDesc = shortDesc;
	return;
}

std::string Creature::getShortDesc( void ) const {
	return _shortDesc;
}

void Creature::setLongDesc( const std::string& longDesc ) {
	_longDesc = longDesc;
	return;
}

std::string Creature::getLongDesc( void ) const {
	return _longDesc;
}

void Creature::setFullDesc( const std::string& fullDesc ) {
	_fullDesc = fullDesc;
	return;
}

std::string Creature::getFullDesc( void ) const {
	return _fullDesc;
}

std::string* Creature::getFullDescP( void ) {
	return &_fullDesc;
}

void Creature::setStrHeight( const std::string& strHeight ) {
	_strHeight = strHeight;
	return;
}

std::string Creature::getStrHeight( void ) const {
	return _strHeight;
}

void Creature::setStrWeight( const std::string& strWeight ) {
	_strWeight = strWeight;
	return;
}

std::string Creature::getStrWeight( void ) const {
	return _strWeight;
}

void Creature::setArea( Area* area ) {
	_area = area;
	return;
}

Area* Creature::getArea( void ) const {
	return _area;
}

void Creature::setRoom( Room* room ) {
	_room = room;
	return;
}

Room* Creature::getRoom( void ) const {
	return _room;
}

void Creature::setCreature( Creature* creature ) {
	_creature = creature;
	return;
}

Creature* Creature::getCreature( void ) const {
	return _creature;
}

Mob* Creature::getMob( void ) const {
	return _mob;
}

void Creature::setMob( Mob* mob ) {
	_mob = mob;
	return;
}

Character* Creature::getCharacter( void ) const {
	return _character;
}

void Creature::setCharacter( Character* character ) {
	_character = character;
	return;
}

void Creature::setPos( const unsigned& pos ) {
	_pos = pos;
	return;
}

unsigned Creature::getPos( void ) const {
	return _pos;
}

void Creature::setRace( const unsigned& race ) { // public
	_race = race;
	return;
}

unsigned Creature::getRace( void ) const { // public
	return _race;
}

void Creature::setClass( const unsigned& class_ ) { // public
	_class = class_;
	return;
}

unsigned Creature::getClass( void ) const { // public
	return _class;
}

void Creature::setLevel( const unsigned& level ) {
	_level = level;
	return;
}

unsigned Creature::getLevel( void ) const {
	return _level;
}

void Creature::setStr( const unsigned& str ) {
	_str = str;
	return;
}

unsigned Creature::getStr( void ) const {
	return _str;
}

void Creature::setMaxStr( const unsigned& maxStr ) {
	_maxStr = maxStr;
	return;
}

unsigned Creature::getMaxStr( void ) const {
	return _maxStr;
}

void Creature::setDex( const unsigned& dex ) {
	_dex = dex;
	return;
}

unsigned Creature::getDex( void ) const {
	return _dex;
}

void Creature::setMaxDex( const unsigned& maxDex ) {
	_maxDex = maxDex;
	return;
}

unsigned Creature::getMaxDex( void ) const {
	return _maxDex;
}

void Creature::setCon( const unsigned& con ) {
	_con = con;
	return;
}

unsigned Creature::getCon( void ) const {
	return _con;
}

void Creature::setMaxCon( const unsigned& maxCon ) {
	_maxCon = maxCon;
	return;
}

unsigned Creature::getMaxCon( void ) const {
	return _maxCon;
}

void Creature::setIntel( const unsigned& intel ) {
	_intel = intel;
	return;
}

unsigned Creature::getIntel( void ) const {
	return _intel;
}

void Creature::setMaxIntel( const unsigned& maxIntel ) {
	_maxIntel = maxIntel;
	return;
}

unsigned Creature::getMaxIntel( void ) const {
	return _maxIntel;
}

void Creature::setWis( const unsigned& wis ) {
	_wis = wis;
	return;
}

unsigned Creature::getWis( void ) const {
	return _wis;
}

void Creature::setMaxWis( const unsigned& maxWis ) {
	_maxWis = maxWis;
	return;
}

unsigned Creature::getMaxWis( void ) const {
	return _maxWis;
}

void Creature::setCha( const unsigned& cha ) {
	_cha = cha;
	return;
}

unsigned Creature::getCha( void ) const {
	return _cha;
}

void Creature::setMaxCha( const unsigned& maxCha ) {
	_maxCha = maxCha;
	return;
}

unsigned Creature::getMaxCha( void ) const {
	return _maxCha;
}

void Creature::setHp( const unsigned& hp ) {
	_hp = hp;
	return;
}

unsigned Creature::getHp( void ) const {
	return _hp;
}

void Creature::setMaxHp( const unsigned& maxHp ) {
	_maxHp = maxHp;
	return;
}

unsigned Creature::getMaxHp( void ) const {
	return _maxHp;
}

void Creature::setMana( const unsigned& mana ) {
	_mana = mana;
	return;
}

unsigned Creature::getMana( void ) const {
	return _mana;
}

void Creature::setMaxMana( const unsigned& maxMana ) {
	_maxMana = maxMana;
	return;
}

unsigned Creature::getMaxMana( void ) const {
	return _maxMana;
}

void Creature::setMove( const unsigned& move ) {
	_move = move;
	return;
}

unsigned Creature::getMove( void ) const {
	return _move;
}

void Creature::setMaxMove( const unsigned& maxMove ) {
	_maxMove = maxMove;
	return;
}

unsigned Creature::getMaxMove( void ) const {
	return _maxMove;
}

void Creature::setAc( const unsigned& ac ) {
	_ac = ac;
	return;
}

unsigned Creature::getAc( void ) const {
	return _ac;
}

void Creature::setAcBash( const int& acBash ) {
	_acBash = acBash;
	return;
}

int Creature::getAcBash( void ) const {
	return _acBash;
}

void Creature::setAcSlash( const int& acSlash ) {
	_acSlash = acSlash;
	return;
}

int Creature::getAcSlash( void ) const {
	return _acSlash;
}

void Creature::setAcPierce( const int& acPierce ) {
	_acPierce = acPierce;
	return;
}

int Creature::getAcPierce( void ) const {
	return _acPierce;
}

void Creature::setAcExotic( const int& acExotic ) {
	_acExotic = acExotic;
	return;
}

int Creature::getAcExotic( void ) const {
	return _acExotic;
}

void Creature::setHr( const unsigned& hr ) {
	_hr = hr;
	return;
}

unsigned Creature::getHr( void ) const {
	return _hr;
}

void Creature::setDr( const unsigned& dr ) {
	_dr = dr;
	return;
}

unsigned Creature::getDr( void ) const {
	return _dr;
}

void Creature::setSaves( const int& saves ) {
	_saves = saves;
	return;
}

int Creature::getSaves( void ) const {
	return _saves;
}

void Creature::setWimpy( const unsigned& wimpy ) {
	_wimpy = wimpy;
	return;
}

unsigned Creature::getWimpy( void ) const {
	return _wimpy;
}

void Creature::setGender( const unsigned& gender ) {
	_gender = gender;
	return;
}

unsigned Creature::getGender( void ) const {
	return _gender;
}

void Creature::setHeight( const unsigned& height ) {
	_height = height;
	return;
}

unsigned Creature::getHeight( void ) const {
	return _height;
}

void Creature::setWeight( const unsigned& weight ) {
	_weight = weight;
	return;
}

unsigned Creature::getWeight( void ) const {
	return _weight;
}

void Creature::setAge( const unsigned& age ) {
	_age = age;
	return;
}

unsigned Creature::getAge( void ) const {
	return _age;
}

void Creature::setGold( const unsigned& gold ) {
	_gold = gold;
	return;
}

unsigned Creature::getGold( void ) const {
	return _gold;
}

void Creature::setSilver( const unsigned& silver ) {
	_silver = silver;
	return;
}

unsigned Creature::getSilver( void ) const {
	return _silver;
}

std::vector< Object* >& Creature::getInventory( void ) { // public
	return _inventory;
}

// General methods...
Object* Creature::add( Object* object ) { // public
	getInventory().push_back( object );
	return object;
}

Object* Creature::getObject( const std::string& name ) { // public
	for ( std::vector< Object* >::iterator it = getInventory().begin(); it != getInventory().end(); ++it )
		if ( str_prefix( name, (*it)->getName() ) )
			return *it;
	return NULL;
}

bool Creature::dropObject( const std::string& name ) { // public
	for ( std::vector< Object* >::iterator it = getInventory().begin(); it != getInventory().end(); ++it ) {
		if ( str_prefix( name, (*it)->getName() ) ) {
			getInventory().erase( it );
			return true;
		}
	}
	return false;
}

bool Creature::drop( Object* object ) { // public
	for ( std::vector< Object* >::iterator it = getInventory().begin(); it != getInventory().end(); ++it ) {
		if ( (*it) == object ) {
			getInventory().erase( it );
			return true;
		}
	}
	return false;
}

void Creature::save( std::ostream& write ) { // public
	write << "// Creature data...\n";
	write << getName() << '\n';
	write << getRace() << ' ' << getClass() << ' ';
	write << getGold() << ' ' << getSilver() << ' ';
	write << getPos() << ' ' << getRoom()->getVnum() << ' ';
	write << getLevel() << '\n';
	write << getStr() << ' ' << getMaxStr() << ' ';
	write << getDex() << ' ' << getMaxDex() << ' ';
	write << getCon() << ' ' << getMaxCon() << ' ';
	write << getIntel() << ' ' << getMaxIntel() << ' ';
	write << getWis() << ' ' << getMaxWis() << ' ';
	write << getCha() << ' ' << getMaxCha() << ' ';
	write << getHp() << ' ' << getMaxHp() << ' ' << getMana() << ' ' << getMaxMana() << ' ' << getMove() << ' ' << getMaxMove() << '\n';
	write << getAc() << ' ' << getAcBash() << ' ' << getAcSlash() << ' ' << getAcPierce() << ' ' << getAcExotic() << ' ';
	write << getHr() << ' ' << getDr() << ' ' << getSaves() << ' ';
	write << getWimpy() << ' ' << getGender() << ' ';
	write << getHeight() << ' ' << getWeight() << ' ' << getAge() << ' ' << getStrHeight() << ' ' << getStrWeight() << '\n';
	write << getShortDesc() << '\n';
	write << getLongDesc() << '\n';
	write << getFullDesc() << "$\n\n";
	return;
}

void Creature::load( std::istream& read ) { // public
	char temp[2048], name[2048], strHeight[2048], strWeight[2048], shortDesc[2048], longDesc[2048], fullDesc[2048];
	unsigned	race = 0, class_ = 0, pos = 0, room = 0, level = 0, str = 0,
				maxStr = 0, dex = 0, maxDex = 0, con = 0, maxCon = 0, intel = 0,
				maxIntel = 0, wis = 0, maxWis = 0, cha = 0, maxCha = 0, hp = 0,
				maxHp = 0, mana = 0, maxMana = 0, move = 0, maxMove = 0, ac = 0,
				hr = 0, dr = 0, wimpy = 0, gender = 0, height = 0, weight = 0,
				age = 0, gold = 0, silver = 0;
	int			acBash = 0, acSlash = 0, acPierce = 0, acExotic = 0, saves = 0;

	// This kills a line of comment in the pfile...
	read.getline( temp, 2048 );

	// load the data
	read.getline( name, 2048 );
	read >> race >> class_ >> gold >> silver >> pos >> room >> level;
	read >> str >> maxStr >> dex >> maxDex >> con >> maxCon >> intel >> maxIntel >> wis >> maxWis >> cha >> maxCha;
	read >> hp >> maxHp >> mana >> maxMana >> move >> maxMove;
	read >> ac >> acBash >> acSlash >> acPierce >> acExotic >> hr >> dr >> saves;
	read >> wimpy >> gender >> height >> weight >> age >> strHeight >> strWeight;
	read.get(); // Kills an extra newline
	read.getline( shortDesc, 2048 );
	read.getline( longDesc, 2048 );
	read.getline( fullDesc, 2048, '$' );

	setName( name );
	setRace( race );
	setClass( class_ );
	setGold( gold );
	setSilver( silver );
	setPos( pos );
	setRoom( World::Instance().getRoom( room ) );
	if ( getRoom() == NULL )
		setRoom( World::Instance().getRoom( 0 ) );
	setLevel( level );
	setStr( str );
	setMaxStr( maxStr );
	setDex( dex );
	setMaxDex( maxDex );
	setCon( con );
	setMaxCon( maxCon );
	setIntel( intel );
	setMaxIntel( maxIntel );
	setWis( wis );
	setMaxWis( maxWis );
	setCha( cha );
	setMaxCha( maxCha );
	setHp( hp );
	setMaxHp( maxHp );
	setMana( mana );
	setMaxMana( maxMana );
	setMove( move );
	setMaxMove( maxMove );
	setAc( ac );
	setAcBash( acBash );
	setAcSlash( acSlash );
	setAcPierce( acPierce );
	setAcExotic( acExotic );
	setHr( hr );
	setDr( dr );
	setSaves( saves );
	setWimpy( wimpy );
	setGender( gender );
	setHeight( height );
	setWeight( weight );
	setAge( age );
	setStrHeight( strHeight );
	setStrWeight( strWeight );
	setShortDesc( shortDesc );
	setLongDesc( longDesc );
	setFullDesc( fullDesc );

	// Kill some more comments and extra newlines...
	read.get();
	read.getline( temp, 2048 );
	read.getline( temp, 2048 );

	return;
}

bool Creature::hasPermission( Creature* creature ) {
	if ( creature->getLevel() <= getLevel()-2 )
		return true;
	return false;
}

// Static methods...
std::string Creature::gender2string( const unsigned& gender ) {
	switch ( gender ) {
		case MALE:		return "male";
		case FEMALE:	return "female";
		default:		return "neutral";
	}
}

unsigned Creature::string2gender( const std::string& gender ) {
	std::string temp = lowerString( trim( gender ) );
	if ( temp == "male" )
		return MALE;
	else if ( temp == "female" )
		return FEMALE;
	else
		return NEUTRAL;
}

std::string Creature::race2string( const unsigned& race ) {
	switch ( race ) {
		case HUMAN:		return "human";
		case ELF:		return "elf";
		case DWARF:		return "dwarf";
		case GOBLIN:	return "goblin";
		default:
			std::string message;
			message << "Default hit in Creature::race2string() in " << __FILE__ << " line " << __LINE__;
			log( message, SERVER );
			return "{RERROR{x";
	}
}

unsigned Creature::string2race( const std::string& race ) {
	std::string temp = lowerString( trim( race ) );
	if ( temp == "human" )
		return HUMAN;
	else if ( temp == "elf" )
		return ELF;
	else if ( temp == "dwarf" )
		return DWARF;
	else if ( temp == "goblin" )
		return GOBLIN;
	else {
		std::string message;
		message << "Default hit in Creature::string2race() in " << __FILE__ << " line " << __LINE__;
		log( message, SERVER );
		return -1;
	}
}

std::string Creature::class2string( const unsigned& class_ ) {
	switch ( class_ ) {
		case MAGE:		return "mage";
		case CLERIC:	return "cleric";
		case WARRIOR:	return "warrior";
		case BANDIT:	return "bandit";
		default:
			std::string message;
			message << "Default hit in Creature::class2string() in " << __FILE__ << " line " << __LINE__;
			log( message, SERVER );
			return "{RERROR{x";
	}
}

unsigned Creature::string2class( const std::string& class_ ) {
	std::string temp = lowerString( trim( class_ ) );
	if ( temp == "mage" )
		return MAGE;
	else if ( temp == "cleric" )
		return CLERIC;
	else if ( temp == "warrior" )
		return WARRIOR;
	else if ( temp == "bandit" )
		return BANDIT;
	else {
		std::string message;
		message << "Default hit in Creature::string2class() in " << __FILE__ << " line " << __LINE__;
		log( message, SERVER );
		return -1;
	}
}

// Associated operators...
